package com.z.redis.util;

import java.lang.management.ManagementFactory;
import java.util.Calendar;

/**
 * 为 Redis 服务端生成全局唯一的请求跟踪 ID，支持日志追踪与调试。
 */
public class WinterId implements Uid{
    private static final char[] pid;
    private static volatile WinterId INSTANCE;
    private Sequencer sequencer;
    class Sequencer {
        final StringBuilder cache = new StringBuilder(); // 重用 StringBuilder 减少内存分配
        int sequence;      // 序列号（同一毫秒内递增）
        long lastTime;     // 上一次生成 ID 的时间戳
        int pidLength;     // 进程 ID 字符长度
        Calendar now = Calendar.getInstance(); // 时间格式化工具

        public Sequencer() {
            cache.append(pid); // 初始化时写入进程 ID（如 "1234_"）
            pidLength = pid.length;
        }

        /**
            * 生成字符型ID（格式：进程ID_年月日时分秒毫秒_序列号）
            * 示例: "1234_20231015143045123_0"
         */
        synchronized String next() {
            long time = System.currentTimeMillis();
            if (time > lastTime) { // 新时间窗口
                sequence = 0;      // 重置序列号
                lastTime = time;
            } else {              // 同一毫秒内
                sequence += 1;    // 递增序列号
            }
            now.setTimeInMillis(time);
            format(cache, now, sequence); // 格式化时间到 cache
            String result = cache.toString();
            cache.setLength(pidLength); // 重置缓存（保留进程ID部分）
            return result;
        }

        void format(StringBuilder cache, Calendar now, int sequence) {
            // 按顺序追加年月日时分秒毫秒（补零对齐）
            int year = now.get(Calendar.YEAR);
            cache.append(year); // 2023

            // 月份（补零）
            int month = now.get(Calendar.MONTH) + 1;
            if (month >= 10) cache.append(month);
            else cache.append('0').append(month);

            // 日、时、分、秒、毫秒（类似处理）
            int dayOfMonth = now.get(Calendar.DAY_OF_MONTH);
            if (dayOfMonth >= 10) cache.append(dayOfMonth);
            else cache.append('0').append(dayOfMonth);

            int hour = now.get(Calendar.HOUR_OF_DAY);
            if (hour >= 10) cache.append(hour);
            else cache.append('0').append(hour);

            int minute = now.get(Calendar.MINUTE);
            if (minute >= 10) cache.append(minute);
            else cache.append('0').append(minute);

            int second = now.get(Calendar.SECOND);
            if (second >= 10) cache.append(second);
            else cache.append('0').append(second);

            int milliSecond = now.get(Calendar.MILLISECOND);
            if (milliSecond >= 100) cache.append(milliSecond);
            else if(milliSecond >= 10) cache.append('0').append(milliSecond);
            else cache.append(0).append(0).append(milliSecond);

            cache.append('_').append(sequence); // 追加序列号
        }
    }

    static {
        // 通过ManagementFactory 获取当前 JVM 进程 ID（如 1234），转为字符数组 ['1','2','3','4','_']
        pid = (ManagementFactory.getRuntimeMXBean().getName().split("@")[0] + "_").toCharArray();
    }

    private WinterId() {
        sequencer = new Sequencer();
    }
    public static WinterId instance() {
        if (INSTANCE != null ) return INSTANCE;
        synchronized (WinterId.class) {
            if(INSTANCE == null){
                INSTANCE = new WinterId();
            }
            return INSTANCE;
        }
    }

    // 生成唯一ID
    @Override
    public String generate(){
        return sequencer.next();
    }

//    @Override
//    public byte[] generateBytes()
//    {
//        throw new UnsupportedOperationException();
//    }
//
//    @Override
//    public long generateLong()
//    {
//        throw new UnsupportedOperationException();
//    }
//
//    @Override
//    public String generateDigits()
//    {
//        return generate();
//    }
}
